import logging

from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from BYD_ERP.utils.pagination import GlobalPagination
from erp_system.serializer.permission_serializer import PermissionsSerializer

from BYD_ERP.utils.base_views import MultipleDestroyMixin
from erp_system.models import PermissionsModel, RolesModel

logger = logging.getLogger('erp')


class PermissionsView(viewsets.ModelViewSet, MultipleDestroyMixin):
    """
        create:
        权限--新增

        权限新增，status：201（成功），return：新增权限信息

        destroy：
        权限--删除单个权限

        权限删除，status：204（成功），return：None

        multiple_delete:
        权限--批量删除

        权限批量删除，status：204（成功），return：None

        update:
        权限--修改

        权限修改，status：200（成功），return：修改权限本身信息，例如：访问路径，method，不包括授权及关联关系

        partial_update:
        权限--局部修改

        权限局部修改，status：200（成功），return：修改权限本身局部信息

        list:
        权限--查看

        获取所有的权限或者单个权限

        find_permissions_by_menu:
        查询属于指定菜单或接口的权限列表，需要传参：menu_id。 比如：/find_permissions_by_menu?menu_id=2

        返回权限列表，status：200（成功），return：返回权限列表

        find_permissions:
        获取当前角色已经授予的权限ID列表和整个项目的所有权限（树形结构）列表，必传参数：rid（角色ID）

        例如：http://127.0.0.1:8000/permissions/find_permissions/?rid=2
        树形权限列表信息，status：200（成功），return：权限信息列表

        retrieve：
        查询某一个指定的权限信息

        查询指定ID的权限，status：200（成功），return：权限信息
    """

    queryset = PermissionsModel.objects.all()
    serializer_class = PermissionsSerializer
    pagination_class = GlobalPagination

    @action(methods=['get'], detail=False)
    def find_permissions_by_menu(self, request, *args, **kwargs):
        menu_id = request.query_params.get('menu_id')
        permissions_list = PermissionsModel.objects.filter(menu__id=menu_id).all()  # menu是关联属性
        # 序列化
        ser = PermissionsSerializer(instance=permissions_list, many=True)
        return Response(ser.data)

    @action(methods=['get'], detail=False)
    def find_permissions(self, request, *args, **kwargs):
        # 返回当前角色的所有已经拥有的权限ID列表，以及ERP系统中所有的权限（树形结构）数据
        result = {}  # 未来要返回的整个字典
        rid = request.query_params.get('rid', None)
        if rid:  # 查询当前角色的所有已经授权的ID
            # flat=True：扁平化
            # distinct()：去重，去除重复数据
            ids = RolesModel.objects.filter(id=rid).values_list('permissions', flat=True).distinct()
            result['ids'] = ids  # 把已经授权的ID列表存入返回字典中

        # 查询整个ERP系统中，所有的权限列表，要求：树形展示
        # values()返回的就是字典
        permission_list = PermissionsModel.objects.values('id', 'name', 'menu__name', 'menu__id', 'menu__parent__id')
        tree_dict = {}  # 表示一个父节点
        tree_data = []  # 整个权限的树形数据

        # 第一步：构建一个二级树
        for item in permission_list:
            tree_dict[item['menu__id']] = item
        for i in tree_dict:
            if tree_dict[i]['menu__parent__id']:  # 这是子菜单（二级）
                pid = tree_dict[i]['menu__parent__id']  # 这就是父菜单的id
                parent = tree_dict[pid]  # 得到父菜单
                child = dict()
                child['menu__id'] = tree_dict[i]['menu__id']
                child['menu__name'] = tree_dict[i]['menu__name']
                child.setdefault('permissions', [])
                # 把当前的子菜单（二级），关联到父菜单中去
                parent.setdefault('children', []).append(child)

                pass
            else:  # 这是所有的父菜单（一级）
                tree_data.append(tree_dict[i])

        # 第二步：在前面二级树形结构的基础上，添加子权限
        for parent in tree_data:
            if 'children' in parent:
                for child in parent['children']:
                    # 得到child(二级)
                    # node：节点
                    for node in permission_list:
                        if node['menu__parent__id'] and node['menu__id'] == child['menu__id']:
                            child['permissions'].append(node)
                            pass
                    pass

        result['tree_data'] = tree_data
        logger.info(tree_data)
        return Response(result)

        pass
